#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2021/3/21 19:19
# @Author  : Hbber
# @Version : 0.0.0
# @File    : demo_plot.py
# @Software: PyCharm
# @Org     : AirCas
# @Describe: 

# @Last Modify Time          @Version        @Description
# --------------------       --------        -----------
# 2021/3/21 19:19            0.0.1           None

"""
This example demonstrates the use of RemoteGraphicsView to improve performance in
applications with heavy load. It works by starting a second process to handle
all graphics rendering, thus freeing up the main process to do its work.

In this example, the update() function is very expensive and is called frequently.
After update() generates a new set of data, it can either plot directly to a local
plot (bottom) or remotely via a RemoteGraphicsView (top), allowing speed comparison
between the two cases. IF you have a multi-core CPU, it should be obvious that the
remote case is much faster.
"""
import json
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import pyqtgraph.widgets.RemoteGraphicsView
import numpy as np
import socket
import sys
from queue import Queue, Empty
import threading

data_queue = Queue()

app = pg.mkQApp()

view = pg.widgets.RemoteGraphicsView.RemoteGraphicsView()
pg.setConfigOptions(antialias=True)  # this will be expensive for the local plot
view.pg.setConfigOptions(antialias=True)  # prettier plots at no cost to the main process!
view.setWindowTitle('pyqtgraph example: RemoteSpeedTest')

label = QtGui.QLabel()
rcheck = QtGui.QCheckBox('plot remote')
rcheck.setChecked(True)
lcheck = QtGui.QCheckBox('plot local')
lplt = pg.PlotWidget()
layout = pg.LayoutWidget()
layout.addWidget(rcheck)
layout.addWidget(lcheck)
layout.addWidget(label)
layout.addWidget(view, row=1, col=0, colspan=3)
layout.addWidget(lplt, row=2, col=0, colspan=3)
layout.resize(800, 800)
layout.show()

# Create a PlotItem in the remote process that will be displayed locally
rplt = view.pg.PlotItem()
rplt._setProxyOptions(deferGetattr=True)  # speeds up access to rplt.plot
view.setCentralItem(rplt)

lastUpdate = pg.ptime.time()
avgFps = 0.0
data1 = np.random.normal(size=100 * 5)


def update():
    global check, label, plt, lastUpdate, avgFps, rpltfunc, data1
    for i in range(4):
        data1[:-1] = data1[1:]  # shift data in the array one sample left
        # (see also: np.roll)
        try:
            data1[-1] = data_queue.get_nowait()
        except Empty as e:
            print('error')
            data1[-1] = 0
            pass

    if rcheck.isChecked():
        rplt.plot(data1, clear=True, _callSync='off')  # We do not expect a return value.
        # By turning off callSync, we tell
        # the proxy that it does not need to
        # wait for a reply from the remote
        # process.
    if lcheck.isChecked():
        lplt.plot(data1, clear=True)

    now = pg.ptime.time()
    fps = 1.0 / (now - lastUpdate)
    lastUpdate = now
    avgFps = avgFps * 0.8 + fps * 0.2
    label.setText("Generating %0.2f fps" % avgFps)


class SocketClientThread(QtCore.QThread):
    def __init__(self):
        super(SocketClientThread, self).__init__()
        try:
            self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.s.connect(('10.0.0.222', 6666))
        except socket.error as msg:
            print(msg)
            sys.exit(1)

    def run(self):
        while True:
            try:
                data = self.s.recv(4096)
            except Exception as e:
                print(e)
                break
            points = json.loads(data)["data_50"]
            print(points[0:10])
            for point in points:
                data_queue.put(point)
        print('Socket Thread Exit!')


timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(40)
socket_client_thread = SocketClientThread()
socket_client_thread.start()


# Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
